home *** CD-ROM | disk | FTP | other *** search
- /*
- MuiClassHeader.c Universal header file MUI custom classes V1.0
- Copyright(C) 1994 Jochen Wiedmann
-
- Computer: Amiga 1200
- Compiler: Dice 3.01
-
- Author: Jochen Wiedmann
- Am Eisteich 9
- 72555 Metzingen
- Germany
- Phone: 07123 / 14881
- Internet: wiedmann@zdv.uni-tuebingen.de
-
- This code implements the usual startup code of a MUI custom class.
- I recommend reading Appendix C (Sample Library Source Code) of the
- RKM: Libraries, Third Edition for a complete understanding of the
- following. Another good choice would be the shared library example
- of the Dice distribution.
-
- Your library should be implmented in another file. You must define the
- following preprocessor symbols with compiler options, when this file
- is compiled:
- LIBNAME: Name of this library, "chess.library" for example
- LIBVERSION: Library version, "40" for example
- LIBREVISION: Library revision, "1" for example
- LIBINITFUNC: The name of the initialization function. Will be called
- with the library base pointer in register a6,
- should return 0 for success, nonzero otherwise.
- LIBTERMFUNC: The name of a function called when the class will be
- removed from the system; will receive the library base
- pointer in register a6.
-
- The following preprocessor symbols may be defined, but don't need to:
- LIBOPENFUNC: Function to be called every time the library is opened.
- Does not make much sense in most cases. (Default is no
- library specific stuff.)
- LIBCLOSEFUNC: Function to be called every time when CloseLibrary() is
- executed. This is the opponent to LIBCLOSEFUNC and does
- not make much sense in most cases either. (Default is no
- library specific stuff.)
- LIBBASESIZE: Size of the library base, "sizeof(struct Library)" for
- example. (This is the default, if LIBBASESIZE isn't
- defined.
-
-
-
-
- WARNINGS - WARNINGS - WARNINGS - WARNINGS - WARNINGS - WARNINGS - WARNINGS
- - This code depends heavily on some assumptions which are fulfilled
- by Dice:
- * All data declared as "const" will go to the code segment
- * The compiler doesn't rearrange the order of the data and code
- items.
- - You may use uninialized data items in your library code. However,
- the startup code will *not* clear the BSS segment. This means
- that you must not depend on an uninitialized variable being zero!
- - You may use the data and bss segment as usual. But remember that
- this data will be global to the library and hence shared by all
- users of the library. And don't forget to recreate the a4 register,
- if you use such data items! (Usually by adding __saveds or
- something similar to your functions.)
-
- EXAMPLE: To create the header of "userdata.mcc", version 40.1 with library
- specific routines InitUserdata and TermUserdata, and a "struct
- UserdataBase" as library base you would do the following:
-
- dcc -DLIBNAME=userdata.mcc -DLIBVERSION=40 -DLIBREVISION=1
- -DLIBINITFUNC=InitUserdata -DLIBTERMFUNC=TermUserdata
- "-DLIBBASESIZE=sizeof(struct UserdataBase)" -c Userdata.c
- */
-
-
-
-
-
- /****************************************************************************
- Include files
- ****************************************************************************/
- #ifndef EXEC_TYPES_H
- #include <exec/types.h>
- #endif
- #ifndef EXEC_NODES_H
- #include <exec/nodes.h>
- #endif
- #ifndef EXEC_RESIDENT_H
- #include <exec/resident.h>
- #endif
- #ifndef EXEC_LIBRARIES_H
- #include <exec/libraries.h>
- #endif
- #ifndef EXEC_INITIALIZERS_H
- #include <exec/initializers.h>
- #endif
- #ifndef DOS_DOS_H
- #include <dos/dos.h>
- #endif
- #ifndef CLIB_EXEC_PROTOS_H
- #include <clib/exec_protos.h>
- #endif
- #ifndef PRAGMAS_EXEC_PRAGMAS_H
- #include <pragmas/exec_pragmas.h>
- #endif
-
-
-
-
-
- /*****************************************************************************
- Compiler specific stuff (Handling register arguments)
- *****************************************************************************/
- #if defined(_DCC)
- #define REG(x) __ ## x
- #define SAVEDS __geta4
- #define ASM
- #define REGARGS __regargs
- #else
- #if defined(__SASC)
- #define REG(x) register __ ## x
- #define SAVEDS __saveds
- #define ASM __asm
- #define REGARGS __regargs
- #else
- #error "Don't know how to handle register arguments for your compiler."
- #endif
- #endif
-
-
-
- /*
- This routine is an entry point if anyone might wish to run the library
- as an executable.
- */
- STATIC LONG DummyStart(VOID){return(-1);}
-
-
-
-
-
-
- /****************************************************************************
- Library name, ID and version string
- ****************************************************************************/
- #define S(x) #x
- const STATIC UBYTE LibName [] = S(LIBNAME);
- const STATIC UBYTE IdString [] = S(LIBNAME) " " S(LIBVERSION) "." \
- S(LIBREVISION) " (" __DATE__ ")\r\n";
- extern const UBYTE VersionTag [];
-
-
-
-
-
-
- /*****************************************************************************
- The following table is used to initialize the library base. See
- exec.library/InitStruct() and "exec/initializers.i" for details.
- *****************************************************************************/
- const STATIC UWORD DataTable[] = { 0xa000 + (int) OFFSET(Node, ln_Type),
- NT_LIBRARY << 8,
- 0x8000 + (int) OFFSET(Node, ln_Name)
- };
- const STATIC ULONG DataTable1[] = { (ULONG) LibName };
- const STATIC UWORD DataTable2[] = { 0xa000 + (int) OFFSET(Library, lib_Flags),
- (LIBF_SUMUSED|LIBF_CHANGED) << 8,
- 0x9000 + (int) OFFSET(Library, lib_Version),
- LIBVERSION,
- 0x9000 + (int) OFFSET(Library, lib_Revision),
- LIBREVISION,
- 0x8000 + (int) OFFSET(Library, lib_IdString)
- };
- const STATIC ULONG DataTable3[] = { (ULONG) IdString,
- 0
- };
-
-
-
-
-
-
- /****************************************************************************
- The following table is expected to be at the beginning of any library.
- ****************************************************************************/
- extern APTR InitTable [];
- const STATIC struct Resident RomTag =
- {
- RTC_MATCHWORD, /* ILLEGAL instruction, magic cookie to identify Resident
- structure */
- &RomTag, /* Additional legality check */
- &RomTag, /* Where to continue looking for Resident structures */
- RTF_AUTOINIT, /* Easy initialization */
- LIBVERSION, /* Library version */
- NT_LIBRARY, /* type of module */
- 0, /* Priority, don't use */
- LibName, /* library name */
- IdString, /* Id string */
- InitTable /* See below */
- };
-
-
-
-
-
-
- /*****************************************************************************
- The following function will be called at startup.
-
- Inputs: LibPtr - pointer to the library base, initialized due to the
- specifications in DataTable
- SegList - BPTR to the segment list
- _SysBase - the usual ExecBase pointer
-
- Result: LibPtr, if all was okay and the library may be linked into the
- system library list. NULL otherwise
- *****************************************************************************/
- STATIC BPTR MySegList;
- SAVEDS ASM struct Library *_LibInit(REG(d0) struct Library *LibPtr,
- REG(a0) BPTR SegList,
- REG(a6) struct ExecBase *_SysBase)
-
- {
- extern ULONG LIBINITFUNC(REG(a6) struct Library *);
-
- MySegList = SegList;
- if (LIBINITFUNC(LibPtr))
- {
- return((BPTR) NULL);
- }
- return(LibPtr);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /****************************************************************************
- The following functions are called from exec.library/OpenLibrary(),
- exec.library/CloseLibrary() and exec.library/ExpungeLibrary(),
- respectively.
-
- Exec puts the library base pointer in a6 and turns off task switching
- while they are executed, so we should not wait too long inside.
- ****************************************************************************/
-
- /*
- This function is called from exec.library/OpenLibrary().
-
- Inputs: LibPtr - pointer to the library base
- Version - the suggested version number
-
- Result: LibPtr, if successful, NULL otherwise
- */
- ASM struct Library *_LibOpen(REG(a6) struct Library *LibPtr,
- REG(d0) ULONG Version)
- {
- #ifdef LIBOPENFUNC
- extern ULONG LIBOPENFUNC(REG(a6) struct Library *);
- #endif
-
- ++LibPtr->lib_OpenCnt;
- LibPtr->lib_Flags &= ~LIBF_DELEXP; /* Prevent delayed expunge */
-
- /* Library specific initialization */
- #ifdef LIBOPENFUNC
- extern ULONG LIBOPENFUNC(LibPtr);
- #endif
-
- return(LibPtr);
- }
-
-
-
-
- /*
- This function is called from exec.library/RemoveLibrary().
-
- Inputs: LibPtr - pointer to the library base.
-
- Result: Segment list of the library (see arguments of _LibInit()),
- if the library isn't opened currently, NULL otherwise.
- */
- extern struct Library *SysBase;
- SAVEDS ASM BPTR _LibExpunge(REG(a6) struct Library *LibPtr)
-
- {
- extern VOID LIBTERMFUNC(REG(a6) struct Library *);
-
- if (LibPtr->lib_OpenCnt)
- { LibPtr->lib_Flags |= LIBF_DELEXP;
- return((BPTR) NULL);
- }
-
- /* Library specific cleanup. */
- LIBTERMFUNC(LibPtr);
-
- /* Remove the library from the library list. */
- Remove((struct Node *) LibPtr);
-
- return(MySegList);
- }
-
-
-
-
-
- /*
- This function is called from exec/CloseLibrary().
-
- Inputs: LibPtr - pointer to the library base as returned from
- OpenLibrary().
-
- Result: Segment list of the library (see arguments of _LibInit), if there
- was a delayed expunge and the library is no longer open, NULL
- otherwise.
- */
- ASM BPTR _LibClose(REG(a6) struct Library *LibPtr)
-
- {
- #ifdef LIBCLOSEFUNC
- extern VOID LIBCLOSEFUNC(REG(a6) struct Library *);
-
- LIBCLOSEFUNC(LibPtr);
- #endif
-
- if (!(--LibPtr->lib_OpenCnt) && (LibPtr->lib_Flags & LIBF_DELEXP))
- { return(_LibExpunge(LibPtr));
- }
- return((BPTR) NULL);
- }
-
-
-
-
-
- /*
- Dummy function to return 0.
- */
- ULONG _LibNull(VOID)
-
- {
- return(0);
- }
-
-
-
-
-
- /****************************************************************************
- Table of functions included in this library; the first 4 are the same
- for any library and for internal use only, MCC_GetClass is the only
- public function of any MUI custom class.
- ****************************************************************************/
- extern REGARGS VOID MCC_GetClass(VOID);
-
- const STATIC APTR LibFuncTable[] =
- {
- _LibOpen,
- _LibClose,
- _LibExpunge,
- _LibNull,
- MCC_GetClass,
- (APTR)-1
- };
-
-
-
-
-
-
- /****************************************************************************
- The romtag specified that we were RTF_AUTOINIT. This means that rt_Init
- points to the table below. (Without RTF_AUTOINIT it would point to a
- routine to run.)
- ****************************************************************************/
- #ifndef LIBBASESIZE
- #define LIBBASESIZE sizeof(struct Library)
- #endif
- const APTR InitTable[4] =
- {
- (APTR)LIBBASESIZE, /* size of library base */
- (APTR)LibFuncTable, /* library function table */
- (APTR)DataTable, /* library base initialization table */
- (APTR)_LibInit, /* function to call on startup */
- };
-